package org.amphiprion.descentv2assistant.dao.xml;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.amphiprion.descentv2assistant.App;
import org.amphiprion.descentv2assistant.ApplicationConstants;
import org.amphiprion.descentv2assistant.entity.Hero;
import org.amphiprion.descentv2assistant.entity.HeroAbility;
import org.amphiprion.descentv2assistant.entity.HeroCharacteristic;
import org.amphiprion.descentv2assistant.entity.HeroFeat;
import org.amphiprion.descentv2assistant.entity.Product;
import org.amphiprion.descentv2assistant.filter.IdFilter;
import org.amphiprion.descentv2assistant.util.PreferenceUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import android.os.Environment;
import android.util.Log;

public class HeroXmlDao extends AbstractXmlDao {
	private static HeroXmlDao instance;

	public static HeroXmlDao getInstance() {
		if (instance == null) {
			instance = new HeroXmlDao();
		}
		return instance;
	}

	public Hero getHero(String heroId) {
		return getHeroes(null, heroId).get(0);
	}

	public List<Hero> getHeroes() {
		return getHeroes(null, null);
	}

	public List<Hero> getHeroes(IdFilter archetypeFilter) {
		return getHeroes(archetypeFilter, null);
	}

	public List<Hero> getHeroes(IdFilter archetypeFilter, String heroId) {

		List<Hero> result = new ArrayList<Hero>();
		String lng = PreferenceUtil.getLanguage();
		InputStream is = null;
		try {
			File f = new File(Environment.getExternalStorageDirectory() + "/" + ApplicationConstants.DIRECTORY + "/heroes.xml");

			if (f.exists()) {
				is = new FileInputStream(f);
			}
			if (is == null) {
				is = App.class.getResourceAsStream("/heroes.xml");
			}

			DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
			builderFactory.setNamespaceAware(true);

			DocumentBuilder builder = builderFactory.newDocumentBuilder();
			Document document = builder.parse(is);

			NodeList list = document.getElementsByTagName("hero");
			for (int i = 0; i < list.getLength(); i++) {
				Element heroNode = (Element) list.item(i);
				String id = heroNode.getAttributes().getNamedItem("id").getNodeValue();

				if (heroId != null && !id.equals(heroId)) {
					continue;
				}

				String archetypeId = heroNode.getAttributes().getNamedItem("archetype").getNodeValue();

				if (archetypeFilter != null && !archetypeFilter.contains(archetypeId)) {
					continue;
				}
				String productId = heroNode.getAttributes().getNamedItem("product").getNodeValue();

				Product product = ProductXmlDao.getInstance().getProduct(productId);
				if (!product.isOwned()) {
					continue;
				}

				Hero hero = new Hero(id);
				// NAME
				Element localizedNode = (Element) heroNode.getElementsByTagName("name").item(0);
				hero.setName(getLocalizedText(localizedNode, lng));
				// Ability
				localizedNode = (Element) heroNode.getElementsByTagName("ability").item(0);
				HeroAbility ability = new HeroAbility();
				ability.setAction(getBooleanAttribute(localizedNode, "action", false));
				ability.setDescription(getLocalizedText(localizedNode, lng));
				hero.setAbility(ability);
				// Ability
				localizedNode = (Element) heroNode.getElementsByTagName("feat").item(0);
				HeroFeat feat = new HeroFeat();
				feat.setAction(getBooleanAttribute(localizedNode, "action", false));
				feat.setDescription(getLocalizedText(localizedNode, lng));
				hero.setFeat(feat);

				// Characteristc
				Element cNode = (Element) heroNode.getElementsByTagName("characteristic").item(0);
				HeroCharacteristic hc = new HeroCharacteristic();
				hc.setSpeed(getIntAttribute(cNode, "speed", 0));
				hc.setHealth(getIntAttribute(cNode, "health", 0));
				hc.setStamina(getIntAttribute(cNode, "stamina", 0));
				hc.setDefense(getAttribute(cNode, "defense", ""));
				hero.setCharacteristic(hc);

				// Attributs
				Element attributeNode = (Element) heroNode.getElementsByTagName("attribute").item(0);
				hero.setMight(getIntAttribute(attributeNode, "might", 0));
				hero.setKnowledge(getIntAttribute(attributeNode, "knowledge", 0));
				hero.setWillpower(getIntAttribute(attributeNode, "willpower", 0));
				hero.setAwareness(getIntAttribute(attributeNode, "awareness", 0));

				hero.setArchetype(ArchetypeXmlDao.getInstance().getArchetype(archetypeId));
				hero.setProduct(product);
				result.add(hero);
			}
			is.close();
			return result;
		} catch (Throwable e) {
			Log.e(ApplicationConstants.PACKAGE, "", e);
			if (is != null) {
				try {
					is.close();
				} catch (Throwable ex) {
				}
			}
			return null;
		}
	}

}
